package org.cgc.gui;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.Iterator;
import java.util.List;

import org.cgc.log.GraphLogic;
import org.cgc.obj.Graph;
import org.cgc.obj.GraphColoringInfo;

public class GraphView {

	private int sx, sy;
	private int r1, r2, r3, r4;
	private int margin;
	private List<Integer> selected;
	private final int CLR1 = 256;
	
	private Graph graph;
	private GraphColoringInfo gci;
	
	public GraphView(Graph graph, GraphColoringInfo gci, List<Integer> selected, int sizeX, int sizeY) {
		sx = sizeX / 2;
		sy = sizeY / 2;
		margin = 20;
		r2 = 5;
		r3 = r2 + 2;
		r1 = Math.min(sx, sy) - 2*r2 - margin;
		r4 = r1 + 20;
		this.selected = selected;
		
		this.graph = graph;
		this.gci = gci;
	}
	
	public void draw(Graphics2D g) {
		
		g.clearRect(0, 0, 2*sx, 2*sy);
		
		int num = graph.getVertNumber();
		
		//calculate colors
		int max = GraphLogic.maxColor(graph);
		
		int step = 0;
		if(max > 0) {
			step = CLR1 / max - 1;
		}
		
		double alpha = 0.;
		double dAlpha = 2 * Math.PI / num;
		
		for(int i = 0; i < num; i++, alpha += dAlpha) {
			int x1 = sx + (int)(r1 * Math.cos(alpha));
			int y1 = sy + (int)(r1 * Math.sin(alpha));
			double alpha2 = alpha;
			for(int j = i; j < num; j++, alpha2 += dAlpha) {
				int x2 = sx + (int)(r1 * Math.cos(alpha2));
				int y2 = sy + (int)(r1 * Math.sin(alpha2));
				if(graph.isEdge(i, j)) {
					if(GraphLogic.forbiddenColors(
						graph, graph.getColor(i), graph.getColor(j))) {
						g.setColor(new Color(200, 0, 0));
					} else {
						g.setColor(new Color(0, 0, 0));
					}
					g.drawLine(x1, y1, x2, y2);
				}
			}
		}
		
		Iterator<Integer> it = selected.iterator();
		while(it.hasNext()) {
			int i = it.next().intValue();
			int x = sx + (int)(r1 * Math.cos(i*dAlpha));
			int y = sy + (int)(r1 * Math.sin(i*dAlpha));
			g.setColor(Color.BLUE);
			g.fillOval(x-r3, y-r3, 2*r3, 2*r3);
		}
		
		for(int i = 0; i < num; i++, alpha += dAlpha) {
			int x = sx + (int)(r1 * Math.cos(alpha));
			int y = sy + (int)(r1 * Math.sin(alpha));
			
			int clr = graph.getColor(i)*step;
			int red = 0;
			int grn = clr;
			int blu = 0;
			g.setColor(new Color(red, grn, blu));
			g.fillOval(x-r2, y-r2, 2*r2, 2*r2);
			
			x = sx + (int)(r4 * Math.cos(alpha));
			y = sy + (int)(r4 * Math.sin(alpha));
			g.setColor(Color.BLACK);
			g.drawString(""+graph.getColor(i), x, y+5);
		}
		
		g.setColor(new Color(0, 0, 0));
		int y = 380;
		g.drawString("Used colors: " + gci.getColorsUsed(), 10, y+20);
		g.drawString("Note: " + gci.getNote(), 10, y+40);
		g.drawString("Average note: " + gci.getAvgNote(), 10, y+60);
		g.drawString("Epochs: " + gci.getEpochs(), 10, y+80);
		g.drawString("Time: " + gci.getTime() + " ms", 10, y+100);
	}
	
	public int getSelectedVertexIndex(int mx, int my) {
		int num = graph.getVertNumber();
		double alpha = 0.;
		double dAlpha = 2 * Math.PI / num;
		
		for(int i = 0; i < num; i++, alpha += dAlpha) {
			int x = sx + (int)(r1 * Math.cos(alpha));
			int y = sy + (int)(r1 * Math.sin(alpha));
			
			if(mx < x-r3) continue;
			if(mx > x+r3) continue;
			if(my < y-r3) continue;
			if(my > y+r3) continue;
			
			return i;
		}
		return -1;
	}
}
